/*
  This file is part of 'Trivial chess'.

  'Trivial chess' is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  'Trivial chess' is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with 'Trivial chess'.  If not, see <http://www.gnu.org/licenses/>.
*/

/* SVN FILE: $Id$ */
/**
 * @author         $Author$
 * @version        $Rev$
 * @lastrevision   $Date$
 * @filesource     $URL$
 */

//#define BOOST_TEST_MODULE Piece
#include <boost/test/unit_test.hpp>
#include "../config.h"


BOOST_AUTO_TEST_SUITE( PieceTest )

const Piece PIECES[] = {
		Piece::PAWN(),
		Piece::BISHOP(),
		Piece::KNIGHT(),
		Piece::ROOK(),
		Piece::QUEEN(),
		Piece::KING(),
		Piece::NIL()
	};

const char* PIECES_STR[] = {"p","b","n","r","q","k","-"};

const int PIECES_LENGTH = 7;

BOOST_AUTO_TEST_CASE( testEqual ) {
	for ( int i = 0; i < PIECES_LENGTH; ++i ) {
		Piece piece = PIECES[i];
		BOOST_CHECK_EQUAL(piece, PIECES[i]);
	}
}

BOOST_AUTO_TEST_CASE( testNotEqual ) {
	for ( int i = 0; i < PIECES_LENGTH; ++i ) {
		Piece piece1 = PIECES[i];
		for ( int j = 0; j < 7; ++j ) {
			Piece piece2 = PIECES[j];
			if ( i != j )
				BOOST_CHECK_NE(piece1, piece2);
		}
	}
}

#define TEST_IS_PIECE(name,num) \
	for ( int i = 0; i < PIECES_LENGTH; ++i ) { \
		Piece piece = PIECES[i]; \
		if ( num == i ) \
			BOOST_CHECK( piece.is##name() ); \
		else \
			BOOST_CHECK( !piece.is##name() ); \
	}

BOOST_AUTO_TEST_CASE( testIsPawn ) {
	TEST_IS_PIECE(Pawn,0);
}

BOOST_AUTO_TEST_CASE( testIsBishop ) {
	TEST_IS_PIECE(Bishop,1);
}

BOOST_AUTO_TEST_CASE( testIsKnight ) {
	TEST_IS_PIECE(Knight,2);
}

BOOST_AUTO_TEST_CASE( testIsRook ) {
	TEST_IS_PIECE(Rook,3);
}

BOOST_AUTO_TEST_CASE( testIsQueen ) {
	TEST_IS_PIECE(Queen,4);
}

BOOST_AUTO_TEST_CASE( testIsKing ) {
	TEST_IS_PIECE(King,5);
}

BOOST_AUTO_TEST_CASE( testIsNil ) {
	TEST_IS_PIECE(Nil,6);
}

#undef TEST_IS_PIECE

BOOST_AUTO_TEST_CASE( testToInt ) {
	for ( int i = 0; i < PIECES_LENGTH; ++i ) {
		Piece piece = PIECES[i];
		BOOST_CHECK_EQUAL(piece.toInt(), i);
	}
}

BOOST_AUTO_TEST_CASE( testFromInt ) {
	for ( int i = 0; i < PIECES_LENGTH; ++i ) {
		Piece piece;
		piece.fromInt(i);
		BOOST_CHECK_EQUAL(piece, PIECES[i]);
	}
}

BOOST_AUTO_TEST_CASE( testPiece_Int ) {
	for ( int i = 0; i < PIECES_LENGTH; ++i ) {
		Piece piece = Piece(i);
		BOOST_CHECK_EQUAL(piece, PIECES[i]);
	}
}

BOOST_AUTO_TEST_CASE( testInc ) {
	int i = 0;
	Piece piece = Piece::BEGIN();
	while ( i < PIECES_LENGTH - 1 ) {
		BOOST_CHECK_EQUAL(PIECES[i], piece);
		++piece;
		++i;
	}
	BOOST_CHECK_EQUAL(piece, Piece::END());
}

BOOST_AUTO_TEST_CASE( testDec ) {
	int i = PIECES_LENGTH - 2;
	Piece piece = Piece::RBEGIN();
	while ( i >= 0 ) {
		BOOST_CHECK_EQUAL(PIECES[i], piece);
		--piece;
		--i;
	}

	BOOST_CHECK_EQUAL(piece, Piece::REND());
}

BOOST_AUTO_TEST_CASE( toStrTest ) {
	for ( int i = 0; i < PIECES_LENGTH; ++i ) {
		Piece piece = PIECES[i];

		BOOST_CHECK_EQUAL(piece.toStr(), PIECES_STR[i]);
	}
}

BOOST_AUTO_TEST_CASE( fromStrTest ) {
	for ( int i = 0; i < PIECES_LENGTH; ++i ) {
		Piece piece;
		piece.fromStr(PIECES_STR[i]);

		BOOST_CHECK_EQUAL(piece, PIECES[i]);
	}
}

BOOST_AUTO_TEST_CASE( isMinor ) {
	BOOST_CHECK(!Piece::PAWN().isMinor());
	BOOST_CHECK(Piece::BISHOP().isMinor());
	BOOST_CHECK(Piece::KNIGHT().isMinor());
	BOOST_CHECK(!Piece::ROOK().isMinor());
	BOOST_CHECK(!Piece::QUEEN().isMinor());
	BOOST_CHECK(!Piece::KING().isMinor());
}

BOOST_AUTO_TEST_CASE( isMajor ) {
	BOOST_CHECK(!Piece::PAWN().isMajor());
	BOOST_CHECK(!Piece::BISHOP().isMajor());
	BOOST_CHECK(!Piece::KNIGHT().isMajor());
	BOOST_CHECK(Piece::ROOK().isMajor());
	BOOST_CHECK(Piece::QUEEN().isMajor());
	BOOST_CHECK(!Piece::KING().isMajor());
}

BOOST_AUTO_TEST_CASE( isLeaper ) {
	BOOST_CHECK(!Piece::PAWN().isLeaper());
	BOOST_CHECK(!Piece::BISHOP().isLeaper());
	BOOST_CHECK(Piece::KNIGHT().isLeaper());
	BOOST_CHECK(!Piece::ROOK().isLeaper());
	BOOST_CHECK(!Piece::QUEEN().isLeaper());
	BOOST_CHECK(Piece::KING().isLeaper());
}

BOOST_AUTO_TEST_CASE( isSlider ) {
	BOOST_CHECK(!Piece::PAWN().isSlider());
	BOOST_CHECK(Piece::BISHOP().isSlider());
	BOOST_CHECK(!Piece::KNIGHT().isSlider());
	BOOST_CHECK(Piece::ROOK().isSlider());
	BOOST_CHECK(Piece::QUEEN().isSlider());
	BOOST_CHECK(!Piece::KING().isSlider());
}

BOOST_AUTO_TEST_SUITE_END()
